home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
8_13.lha
/
8_13
/
8_13a.c
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
5KB
|
283 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
/ match a pattern on the input stream
/ %d looks for an integer & stops at the first
/ non-integer character
/ %o looks for an octal integer & stops ...
/ %x looks for a hexadecimal integer & stops ...
/ %i looks for a C++ integer & stops ...
/ %f looks for a floating point number & stops ...
/ %c matches a single character
/ %[xyz] matches a character within the set
/ %[^xyz] matches a character not within the set
/ %s matches a white-space delineated string
/ % may be followed by a field width
/ %% matches %
/ ' ' matches any white space
/ 'X' matches the character X
include <pat.h> /* DELETE */
include <ctype.h> /* DELETE */
include <limits.h> /* DELETE */
include <stdlib.h> /* DELETE */
include "8_13b.c" /* DELETE */
nt pat::match(char *pattern)
// reset base ptr to pt to beginning of buffer
ebp->setbuffering();
// loop through the pattern looking
// for things to match.
int goodpattern = 1;
while (*pattern && goodpattern)
{
int c = ebp->sgetc();
char p = *pattern++;
/ define a couple of small macros for
/ some common sequences
define Next() \
ebp->stossc(), c = ebp->sgetc()
define WNext() \
width--, ebp->stossc(), c = ebp->sgetc()
define doloop(testfunc) \
do { Next(); } while (testfunc(c))
define dowloop(testfunc) \
do { width--; ebp->stossc(); \
} while ((width > 0) && \
testfunc(c = ebp->sgetc()))
switch (p)
{
// space matches arbitrary white space
case ' ':
if (isspace(c))
doloop(isspace);
else
goodpattern = 0;
break;
// a pattern: %d, %f, %c, %s, %%
case '%':
p = *pattern++;
// check pattern for a field
// width specification
long width = LONG_MAX;
if (isdigit(p))
{
width = strtol(&pattern[-1],
&pattern, 10);
p = *pattern++;
}
// the default for these two is 1
else if ((p == '[') || (p == 'c'))
width = 1;
// check for patterns which
// toss white space first
switch (p)
{
case 'd': case 'f':
case 'o': case 'x':
case 'i': case 's':
if (isspace(c))
doloop(isspace);
}
// now skip past the particular type
switch (p)
{
// decimal number
case 'd':
if ((width > 0) &&
((c == '-') || (c == '+')))
WNext();
if ((width > 0) && isdigit(c))
dowloop(isdigit);
else
goodpattern = 0;
break;
// octal number
case 'o':
if ((width > 0) &&
((c == '-') || (c == '+')))
WNext();
if ((width > 0) && isodigit(c))
dowloop(isodigit);
else
goodpattern = 0;
break;
// hexdecimal number
case 'x':
if ((width > 0) &&
((c == '-') || (c == '+')))
WNext();
if ((width > 0) && isxdigit(c))
dowloop(isxdigit);
else
goodpattern = 0;
break;
// decimal, octal or hex number
case 'i':
if ((width > 0) &&
((c == '-') || (c == '+')))
WNext();
// check for leading 0 or 0x
if ((width > 0) && (c == '0'))
{
WNext();
if ((width > 0) &&
((c == 'x') || (c == 'X')))
WNext();
}
if ((width > 0) && isdigit(c))
dowloop(isdigit);
else
goodpattern = 0;
break;
// floating point
case 'f':
if ((width > 0) &&
((c == '-') || (c == '+')))
WNext();
int digitsbefore = 0;
int hasdecimal = 0;
int digitsafter = 0;
int hasexponent = 0;
if ((width > 0) && isdigit(c))
{
digitsbefore = 1;
dowloop(isdigit);
}
if ((width > 0) && (c == '.'))
{
hasdecimal = 1;
WNext();
if (isdigit(c))
{
digitsafter = 1;
dowloop(isdigit);
}
}
if ((width > 0) &&
((c == 'e') || (c == 'E')))
{
hasexponent = 1;
WNext();
if ((width > 0) &&
((c == '-') || (c == '+')))
WNext();
if ((width > 0) && isdigit(c))
dowloop(isdigit);
else
goodpattern = 0;
}
if (!((digitsbefore &&
(hasdecimal ||
hasexponent)) ||
digitsafter))
goodpattern = 0;
break;
// any string. leading white
// space was tossed above
case 's':
if (width > 0)
dowloop(!isspace);
break;
// a scanset
case '[':
int x = 0;
char *patbegin = pattern;
if (pattern[1] == '^')
{
x = 1;
patbegin++;
}
while ((width > 0) &&
checkcharset(patbegin, x, c))
WNext();
// found the right # of chars?
if (width > 0)
goodpattern = 0;
pattern += x + 2 +
checkcharset(patbegin, 0, -1);
break;
// any single character
case 'c':
while ((width > 0) &&
(c != EOF))
WNext();
if (width > 0)
goodpattern = 0;
break;
// match single %
case '%':
while ((width > 0) &&
(c == '%'))
WNext();
if (width > 0)
goodpattern = 0;
break;
// unknown pattern
default:
goodpattern = 0;
break;
}
break;
// non-pattern, match the character
default:
if (c == p)
ebp->stossc();
else
goodpattern = 0;
break;
}
}
ebp->resetbuffering();
return goodpattern;